home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac Magazin/MacEasy 11
/
Mac Magazin and MacEasy Magazine CD - Issue 11.iso
/
Sharewarebibliothek
/
Entwickler
/
WASTE 1.1 C
/
WEScraps.c
< prev
next >
Wrap
Text File
|
1995-04-29
|
12KB
|
416 lines
// { WASTE PROJECT: }
// { Routines for manipulating style scraps and object soups }
// { Copyright © 1993-1994 Marco Piovanelli }
// { All Rights Reserved }
#include "WASTEIntf.h"
pascal OSErr _WEPrependStyle(Handle hStyleScrap, WERunInfo *info, long offsetDelta)
{
// { compare the stylistic attributes in info with the first element of the specified }
// { style scrap: if they differ, prepend a new element to the style scrap. }
// { in any case, advance all character offsets in the style scrap by offsetDelta }
TEStyleScrapPtr pScrap;
Size scrapSize;
short i;
OSErr err;
pScrap = *(TEStyleScrapHandle)hStyleScrap;
// { compare this style info with that stored in the first element of our private style scrap }
if (_WEBlockCmp((Ptr)&pScrap->scrpStyleTab[0].scrpTEAttrs, (Ptr)&info->runAttrs,
sizeof(TERunAttributes))
== false)
{
// { leng the style scrap }
scrapSize = GetHandleSize(hStyleScrap);
SetHandleSize(hStyleScrap, scrapSize + sizeof(TEStyleScrapElement));
err = MemError();
if (err != noErr)
return err;
// { move old contents forward }
pScrap = *(TEStyleScrapHandle)hStyleScrap;
BlockMoveData(&pScrap->scrpStyleTab[0], &pScrap->scrpStyleTab[1], scrapSize - sizeof(short));
// { insert a new element at the beginning }
pScrap->scrpStyleTab[0].scrpStartChar = 0;
pScrap->scrpStyleTab[0].scrpTEAttrs = *(TERunAttributes *)&info->runAttrs;
// { increment scrap counter }
pScrap->scrpNStyles = pScrap->scrpNStyles + 1;
} // { if not _WEBlockCmp }
// { update char offsets within the style scrap }
for(i = pScrap->scrpNStyles - 1; i>0; i--)
{
pScrap->scrpStyleTab[i].scrpStartChar = pScrap->scrpStyleTab[i].scrpStartChar + offsetDelta;
}
// { return result code }
return noErr;
} // { _WEPrependStyle }
pascal OSErr _WEAppendStyle(Handle hStyleScrap, WERunInfo *info, long offset)
{
// { compare the stylistic attributes in info with the last element of the specified }
// { style scrap: if they differ, append a new element to the style scrap. }
TEStyleScrapPtr pScrap;
TEStyleScrapElement element;
OSErr err;
pScrap = *(TEStyleScrapHandle)hStyleScrap;
// { compare this style info with that stored in the first element of our private style scrap }
if (_WEBlockCmp((Ptr)&pScrap->scrpStyleTab[pScrap->scrpNStyles - 1].scrpTEAttrs,
(Ptr)&info->runAttrs, sizeof(TERunAttributes)) == false)
{
// { create a new style scrap element }
element.scrpStartChar = offset;
element.scrpTEAttrs = *(TERunAttributes *)&info->runAttrs;
// { append it at the end of the style scrap }
err = PtrAndHand(&element, hStyleScrap, sizeof(element));
err = MemError();
if (err != noErr)
return err;
// { increment scrap counter }
pScrap = *(TEStyleScrapHandle)hStyleScrap;
pScrap->scrpNStyles = pScrap->scrpNStyles + 1;
} // { if not _WEBlockCmp }
// { return result code }
return noErr;
} // { _WEAppendStyle }
pascal OSErr _WEPrependObject(Handle hSoup, WERunInfo *info, long offsetDelta)
{
// { if info describes an embedded object, prepend a new object descriptor, }
// { complete with the associated object data, to the specified soup. }
// { in any case, advance all character offsets in the soup by offsetDelta }
WEObjectDescPtr pDesc;
WESoupPtr pSoup;
Size soupSize, objectDataSize, extraSize;
OSErr err;
// { get size of existing soup }
soupSize = GetHandleSize(hSoup);
// { extract object descriptor handle from WERunInfo record }
// { if hObject is non-NIL, info describes an embedded object }
if (info->runAttrs.runStyle.tsObject != kNullObject)
{
pDesc = *(WEObjectDescHandle)(info->runAttrs.runStyle.tsObject);
// { get size of object data }
objectDataSize = GetHandleSize(pDesc->objectDataHandle);
// { extra size to add to existing soup is descriptor size + object data size }
extraSize = sizeof(WESoup) + objectDataSize;
// { resize the soup }
SetHandleSize(hSoup, soupSize + extraSize);
err = MemError();
if (err != noErr)
return err;
// { move old contents forward }
pSoup = *(WESoupHandle)hSoup;
BlockMoveData((Ptr)pSoup, (Ptr)pSoup + extraSize, soupSize);
// { insert the new object descriptor at the beginning }
_WEBlockClr((Ptr)pSoup, sizeof(WESoup));
pDesc = *(WEObjectDescHandle)(info->runAttrs.runStyle.tsObject);
pSoup->soupType = pDesc->objectType;
pSoup->soupSize = pDesc->objectSize;
pSoup->soupDataSize = objectDataSize;
// { copy the object data }
BlockMoveData(*pDesc->objectDataHandle, (Ptr)pSoup + sizeof(WESoup), objectDataSize);
}
else
{
pSoup = *(WESoupHandle)hSoup;
extraSize = 0;
}
// { update char offsets within the soup }
while (soupSize > 0)
{
pSoup = (WESoupPtr)((Ptr)pSoup + extraSize);
pSoup->soupOffset = pSoup->soupOffset + offsetDelta;
extraSize = pSoup->soupDataSize + sizeof(WESoup);
soupSize = soupSize - extraSize;
}
return noErr;
} // { _WEPrependObject }
pascal OSErr _WEAppendObject(Handle hSoup, WERunInfo *info, long offset)
{
// { if info describes an embedded object, append a new object descriptor, }
// { complete with the associated object data, to the specified soup. }
WEObjectDescPtr pDesc;
Handle hObjectData;
WESoup soupItem;
Boolean saveDataLock;
OSErr err;
if (info->runAttrs.runStyle.tsObject != kNullObject)
{
pDesc = *(WEObjectDescHandle)info->runAttrs.runStyle.tsObject;
hObjectData = pDesc->objectDataHandle;
// { fill in a soup item }
_WEBlockClr((Ptr)&soupItem, sizeof(soupItem));
soupItem.soupOffset = offset;
soupItem.soupType = pDesc->objectType;
soupItem.soupSize = pDesc->objectSize;
soupItem.soupDataSize = GetHandleSize(hObjectData);
// { append it to the soup handle }
PtrAndHand(&soupItem, hSoup, sizeof(soupItem));
err = MemError();
if (err != noErr) return err;
// { append the actual object data to the soup handle }
saveDataLock = _WESetHandleLock(hObjectData, true);
PtrAndHand(*hObjectData, hSoup, soupItem.soupDataSize);
err = MemError();
_WESetHandleLock(hObjectData, saveDataLock);
if (err != noErr) return err;
} // { if object reference is not NIL }
// { clear result code }
return noErr;
} // { _WEAppendObject }
pascal OSErr WECopyRange(long rangeStart, long rangeEnd, Handle hText, Handle
hStyles, Handle hSoup, WEHandle hWE)
{
// { Make a copy of the specified range of text: store the characters in hText }
// { and the associated style scrap in hStyles. The handles are resized as necessary. }
// { Specify NIL in hText or hStyles if you don't want the corresponding info returned. }
WEPtr pWE;
long rangeLength;
long firstRun, nRuns, i;
long startChar;
WERunInfo info;
short *pElement;
Boolean saveWELock;
OSErr err;
TEStyleScrapElementPtr pElem2;
// { lock the WE record }
saveWELock = _WESetHandleLock((Handle)hWE, true);
pWE = *hWE;
// { range-check parameters and reorder them if necessary }
rangeStart = _WEPinInRange(rangeStart, 0, pWE->textLength);
rangeEnd = _WEPinInRange(rangeEnd, 0, pWE->textLength);
_WEReorder(&rangeStart, &rangeEnd);
rangeLength = rangeEnd - rangeStart;
if (hText != nil)
{
// { resize the given handle }
SetHandleSize(hText, rangeLength);
err = MemError();
if (err != noErr)
{
goto cleanup;
}
// { copy the text range }
BlockMoveData((Ptr)*pWE->hText + rangeStart, (Ptr)*hText, rangeLength);
}
// { make the soup handle zero-length }
if (hSoup != nil)
{
SetHandleSize(hSoup, 0);
err = MemError();
if (err != noErr)
goto cleanup;
}
if (hStyles != nil || hSoup != nil)
{
// { count how many style runs there are in the selection range }
firstRun = _WEOffsetToRun(rangeStart, hWE);
nRuns = _WEOffsetToRun(rangeEnd - 1, hWE) - firstRun + 1;
if (hStyles != nil)
{
// { resize the given style scrap handle and lock it in high heap }
SetHandleSize((Handle)hStyles, (((long)nRuns) * sizeof(ScrpSTElement)) + 2);
err = MemError();
if (err != noErr)
goto cleanup;
HLockHi((Handle)hStyles);
pElement = (short *)*hStyles;
// { fill in the style count in the style scrap }
// { *** POTENTIAL PROBLEM: if nRuns > 32767, scrpNStyles will be invalid *** }
*pElement = nRuns;
pElement++;
}
pElem2 = (TEStyleScrapElementPtr)pElement;
// { loop through every style run in the selection range }
for(i = 0; i<nRuns; i++)
{
_WEGetIndStyle(firstRun + i, &info, hWE);
// { calculate the start character for this style run, relative to the beginning of the range }
startChar = info.runStart - rangeStart;
if (startChar < 0)
{
startChar = 0;
info.runAttrs.runStyle.tsObject = kNullObject;
}
if (hStyles != nil)
{
info.runAttrs.runStyle.tsFlags = 0; // { don't export internal flags }
pElem2->scrpStartChar = startChar;
pElem2->scrpTEAttrs = *(TERunAttributes *)&info.runAttrs;
pElem2++;
}
if (hSoup != nil)
{
// { if this style run references an embedded object, append it to the "soup" }
if (info.runAttrs.runStyle.tsObject != kNullObject)
{
err = _WEAppendObject(hSoup, &info, startChar);
if (err != noErr)
goto cleanup;
}
}
}
}
// { clear result code }
err = noErr;
cleanup:
// { unlock the style scrap handle }
if (hStyles != nil)
HUnlock((Handle)hStyles);
// { unlock the WE record }
_WESetHandleLock((Handle)hWE, saveWELock);
// { return result code }
return err;
}
pascal OSErr WECopy(WEHandle hWE)
{
// { Copy the selection range to the desk scrap }
WEPtr pWE;
AEDesc d[3];
WEObjectDescHandle hObjectDesc;
Handle hItem;
Size itemSize;
short i, numTypes;
Boolean saveWELock, saveDataLock;
Boolean disposeData;
OSErr err;
d[0].dataHandle = nil;
d[1].dataHandle = nil;
d[2].dataHandle = nil;
disposeData = false;
// { lock the WE record }
saveWELock = _WESetHandleLock((Handle)hWE, true);
pWE = *hWE;
// { return weEmptySelectionErr if the selection range is empty }
if (pWE->selStart == pWE->selEnd)
{
err = weEmptySelectionErr;
goto cleanup;
}
// { clear the desk scrap }
err = ZeroScrap();
if (err != noErr)
goto cleanup;
// { if the selection range consists of an embedded object, copy that }
if (WEGetSelectedObject(&hObjectDesc, hWE) == noErr)
{
d[0] = **(AEDesc **)(hObjectDesc);
numTypes = 1;
}
else
{
// { allocate three zero-length handles to hold the text, the styles and the "soup" }
for (i=0; i<3; i++)
{
err = _WEAllocate(0, kAllocTemp, &d[i].dataHandle);
if (err != noErr)
goto cleanup;
}
// { make a copy of the selection text and styles and create an object "soup" }
err = WECopyRange(pWE->selStart, pWE->selEnd, d[0].dataHandle,
d[1].dataHandle, d[2].dataHandle, hWE);
if (err != noErr)
goto cleanup;
// { tag the data }
d[0].descriptorType = kTypeText;
d[1].descriptorType = kTypeStyles;
d[2].descriptorType = kTypeSoup;
numTypes = 3;
disposeData = true;
}
// { copy the items to the desk scrap }
for (i= 0; i<numTypes; i++)
{
hItem = d[i].dataHandle;
itemSize = GetHandleSize(hItem);
if (itemSize > 0)
{
saveDataLock = _WESetHandleLock(hItem, true);
err = PutScrap(itemSize, d[i].descriptorType, *hItem);
_WESetHandleLock(hItem, saveDataLock);
if (err != noErr)
goto cleanup;
}
}
// { clear result code }
err = noErr;
cleanup:
// { clean up }
if (disposeData)
{
_WEForgetHandle(&d[0].dataHandle);
_WEForgetHandle(&d[1].dataHandle);
_WEForgetHandle(&d[2].dataHandle);
}
_WESetHandleLock((Handle)hWE, saveWELock);
return err;
}